package com.lanju.app.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.dxl.common.spring.AppCtxHolder;
import com.google.gson.Gson;
import com.lanju.app.message.bean.BaseRequest;
import com.lanju.app.message.bean.BaseResponse;
import com.lanju.app.service.AppService;
import com.lanju.app.util.AppUtil;
import com.lanju.entity.User;

/**
 * App入口控制层
 */
@Controller
@SuppressWarnings("rawtypes")
public class AppController {
	private static Logger log = Logger.getLogger(AppController.class);

	private static String encode = "UTF-8";

	private static Map<String, Class> requestClassPool = new HashMap<String, Class>();

	private static String requestClass = "com.lanju.app.message.bean.$actionCode$Request";

	private Gson gson = AppUtil.createGson();

	// android入口
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/android")
	public void android(HttpServletRequest request, HttpServletResponse response) {
		BaseResponse res = null;
		BaseRequest br = null;
		String actionCode = null;
		try {
			br = parseRequest(request);
			if (br != null) {
				actionCode = br.getActionCode();
				AppService service = (AppService) AppCtxHolder.getBean(actionCode + "Service");
				String userId = checkLawyerId(br.getToken());
				User user = null;
				if (StringUtils.isNotBlank(userId))
					user = service.getUser(userId);
				if (actionCode.startsWith("B0")) {
					// 不校验
					res = service.doService(br, user);
				}else{
					if (null == user) {
						res = new BaseResponse();
						res.setSuccess(false);
						res.setMessage("没有用户");
					} else {
						res = service.doService(br, user);
					}
				}
			}
		} catch (Exception e) {
			res = new BaseResponse();
			if (null == br) {
				res.setMessage("数据格式错误");
				log.warn("请求出错", e);
			} else {
				res.setMessage("服务执行错误," + br.getActionCode() + " token:" + br.getToken());
				log.error("请求br.getActionCode()出错", e);
			}
		}

		resp(response, res);
	}

	// iOS入口
	@RequestMapping(value = "/ios")
	public void ios(HttpServletRequest request, HttpServletResponse response) {

		android(request, response);
	}

	/**
	 * 校验token返回lawyerid
	 * 
	 * @param token
	 * @return
	 */
	private String checkLawyerId(String token) {
		// TODO 解析
		return token;
	}

	private String resv(HttpServletRequest request) throws Exception {
		StringBuilder sb = new StringBuilder();
		try {
			InputStream is = request.getInputStream();
			Reader reader = new InputStreamReader(is, encode);
			BufferedReader br = new BufferedReader(reader);
			String r_line = "";
			while (null != (r_line = br.readLine())) {
				sb.append(r_line);
			}
			return sb.toString();
		} catch (IOException e) {
			log.warn("读取流出错！", e);
			throw e;
		}

	}

	private void resp(HttpServletResponse response, BaseResponse brb) {
		try {
			response.setContentType("text/html;charset=UTF-8");
			String result = gson.toJson(brb);
			if (log.isDebugEnabled()) {
				log.debug("<<<" + result);
			}
			response.getWriter().write(result);
			response.flushBuffer();
		} catch (IOException e) {
			log.error("写入流出错", e);
		}
	}

	@SuppressWarnings("unchecked")
	private BaseRequest parseRequest(HttpServletRequest request) throws Exception {
		String json = null;
		try {
			json = resv(request);
			if (log.isDebugEnabled()) {
				log.debug(">>>" + json);
			}
			if (StringUtils.isNoneBlank(json)) {
				BaseRequest br = gson.fromJson(json, BaseRequest.class);
				if (br != null) {
					String actionCode = br.getActionCode();
					Class target_class = requestClassPool.get(actionCode);
					if (null == target_class) {
						String class_info = requestClass.replace("$actionCode$", actionCode);
						target_class = Class.forName(class_info);
						requestClassPool.put(actionCode, target_class);
					}
					return (BaseRequest) gson.fromJson(json, target_class);
				}
			}
			throw new Exception("json:" + json);
		} catch (Exception e) {
			throw new Exception("传入json：" + json);
		}
	}
}
